package com.xiaochong.tir.manager.config.druid;

import com.xiaochong.service.common.config.redis.RedisServer;
import com.xiaochong.tir.common.data.mapper.base.BaseDao;
import com.xiaochong.tir.common.data.po.Account;
import com.xiaochong.tir.common.data.po.OperationLog;
import com.xiaochong.tir.common.util.RedisKeysUtils;
import com.xiaochong.tir.manager.filter.SessionManager;
import com.xiaochong.tir.manager.service.OperationLogService;
import com.xiaochong.tir.manager.util.SessionUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * Created by admin on 2018/6/1.
 */
@Component
@Aspect
public class OperationAspect {

    @Autowired
    private OperationLogService operationLogService;
    @Autowired
    private RedisServer redisServer;

    @Pointcut("@annotation(com.xiaochong.tir.manager.config.druid.Operation)")
    private void cut(){}

    @After("cut()")
    public void advice(JoinPoint joinPoint){
        OperationLog operationLog = new OperationLog();
        Object[] args = joinPoint.getArgs();//访问目标方法的参数
        Signature signature = joinPoint.getSignature();//获取连接点的方法签名对象
        Object object = joinPoint.getTarget();//获取连接点所在的目标对象
        String className = object.getClass().toString().replace("class","").trim();
        if (args != null && args.length > 0 ) {
            operationLog.setClassname(className);//类名
            operationLog.setMethodname(signature.getName());
            if(signature.getName().contains("insert")||signature.getName().contains("add")){
                operationLog.setLogtype(String.valueOf(2));
                JSONArray array =JSONArray.fromObject(args[0]);
                for (int i = 0; i < array.size(); i++) {
                    JSONObject obj = array.getJSONObject(i);
                    removeFields(obj);
                    operationLog.setContent("新增:"+removeFields(obj));
                    insertOperation(operationLog);
                }
            }else if(signature.getName().contains("update")){
                JSONObject objOld =JSONObject.fromObject(args[1]);
                JSONObject objNew = JSONObject.fromObject(args[0]);
                String content = getDeffrentFields(objOld,objNew);
                if(content.contains("enableFlag")&&!content.contains("deleteFlag")){
                    operationLog.setLogtype(String.valueOf(3));
                    if(JSONObject.fromObject(args[0]).get("enableFlag").equals(true)){
                        operationLog.setContent("id="+JSONObject.fromObject(args[0]).get("id") + ",启用");
                    }else {
                        operationLog.setContent("id="+JSONObject.fromObject(args[0]).get("id") + ",停用");
                    }
                    insertOperation(operationLog);
                } else if(content.contains("tatus")&& !content.contains("klineStatus")){
                    operationLog.setLogtype(String.valueOf(3));
                    if(JSONObject.fromObject(args[0]).get("status").equals(1)){
                        operationLog.setContent("id="+JSONObject.fromObject(args[0]).get("id") + ",恢复");
                    }else{
                        operationLog.setContent("id="+JSONObject.fromObject(args[0]).get("id") + ",禁用");
                    }
                    insertOperation(operationLog);
                } else if(content.contains("deleteFlag")||content.contains("isDel")){
                    operationLog.setLogtype(String.valueOf(1));
                    operationLog.setContent("删除:" + JSONObject.fromObject(args[0]).get("id"));
                    insertOperation(operationLog);
                } else if(!content.contains("enableFlag")&&!content.contains("deleteFlag")){
                    operationLog.setLogtype(String.valueOf(3));
                    if(StringUtils.isNotBlank(content.substring(content.indexOf("由")+1))){
                        operationLog.setContent(content);
                        insertOperation(operationLog);
                    }
                }
            }else if(signature.getName().contains("delete")){
                operationLog.setLogtype(String.valueOf(1));
                if(JSONArray.fromObject(args[1]).size()>0){
                    JSONObject obj = JSONObject.fromObject(args[1]);
                    operationLog.setContent("删除:"+removeFields(obj));
                    insertOperation(operationLog);
                }
            }
        }
    }

    //添加用户信息，插入数据
    public void insertOperation(OperationLog operationLog){
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        Account account = SessionManager.getLoginAccount(request.getSession());//获取当前用户
        operationLog.setLogname(redisServer.get(RedisKeysUtils.LOGINNAME));
        operationLog.setOperaterId(account.getId());
        operationLog.setOperaterNickname(account.getNickName());
        operationLog.setCreatetime(new Date());
        operationLogService.insertSelective(operationLog);//插入数据
    }

    //比较map
    public String getDeffrentFields(Map<String,Object> map1,Map<String,Object> map2){
        Iterator iter = map1.keySet().iterator();
        String res = "id="+map1.get("id")+",由";
        while (iter.hasNext()){
            String mapKey = (String) iter.next();
            if("".equals(String.valueOf(map2.get(mapKey))) || "null".equals(String.valueOf(map2.get(mapKey)))
                    ||mapKey.contains("Time")
                    ||mapKey.contains("content")
                    ||mapKey.contains("contentSummary")
                    ||mapKey.contains("Url")
                    ||mapKey.contains("Hash")
                    ||mapKey.contains("serialVersionUID")
                    ||mapKey.contains("downloadCount")
                    ||mapKey.contains("tourCount")
                    ||mapKey.contains("fixed")
                    ||mapKey.contains("fixed")
                    ||mapKey.contains("Ids")
                    ||mapKey.contains("List")
                    ||mapKey.contains("shelfFlag")
                    ||mapKey.contains("createAt")
                    ||mapKey.contains("updatedAt")
                    ||mapKey.contains("operateType")
                    ||mapKey.contains("isCheck")
                    ||mapKey.contains("time")
                    ||mapKey.contains("personExt")
                    ||mapKey.contains("courseExt")
                    ||mapKey.contains("intruduction")
                    ||mapKey.contains("ext")
                    ||mapKey.contains("zeAffiliate")
                    ||mapKey.contains("pageSize")
                    ||mapKey.contains("articleContent")){continue;}
            if(!map1.get(mapKey).equals(map2.get(mapKey))){
                res+= mapKey + ":" + map1.get(mapKey) + "改为"+":"+map2.get(mapKey)+",";
            }
        }
        return res;
    }

    //去掉长度太长的字段
    public String removeFields(Map<String,Object> map){
        Iterator iter = map.keySet().iterator();
        String res = "";
        while (iter.hasNext()){
            String mapKey = (String) iter.next();
            if(mapKey.contains("Time")
                    ||mapKey.contains("page")
                    ||mapKey.contains("count")
                    ||mapKey.contains("content")
                    ||mapKey.contains("contentSummary")
                    ||mapKey.contains("list")
                    ||mapKey.contains("limit")
                    ||mapKey.contains("operateType")
                    ||mapKey.contains("isCheck")
                    ||mapKey.contains("newStatusName")
                    ||mapKey.contains("head")
                    ||mapKey.contains("statusName")
                    ||mapKey.contains("updatedAt")
                    ||mapKey.contains("sysUserId")
                    ||mapKey.contains("channelsNames")
                    ||mapKey.contains("Count")
                    ||mapKey.contains("time")
                    ||mapKey.contains("createdAt")
                    ||mapKey.contains("intruduction")
                    ||mapKey.contains("ext")
                    ||mapKey.contains("zeAffiliate")
                    ||mapKey.contains("imageUrl")
                    ||mapKey.contains("currencyIndustryList")
                    ||mapKey.contains("currencyConceptList")){continue;}
            res+= mapKey + ":" + map.get(mapKey)+",";
        }
        return res;
    }
}
